/*******************************************************************************
 * Creator: Jose Castillo jocasal@gmail.com
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL DANIEL MURPHY BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ******************************************************************************/
/**
 * Created at 25 Mar, 2011
 */

package packbridge;

  // import flash.display.Sprite;
  // import flash.events.Event;

import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.Fixture;
import org.jbox2d.dynamics.FixtureDef;
import org.jbox2d.dynamics.World;
import org.jbox2d.dynamics.joints.PrismaticJoint;
import org.jbox2d.dynamics.joints.PrismaticJointDef;
import org.jbox2d.dynamics.joints.RevoluteJoint;
import org.jbox2d.dynamics.joints.RevoluteJointDef;

   public class coche {

      public int ITERATIONS    = 30;
      public float TIME_STEP    = (float) (1.0 / 60.0);
      public int SCREEN_WIDTH          = 800;
      public int SCREEN_HEIGHT     = 500;
      public int DRAW_SCALE      = 50;

      public World world;
      public Body cart;
      public Body wheel1;
      public Body wheel2;
      public Body axle1 ;
      public Body axle2;
      public RevoluteJoint motor1 ;
      public RevoluteJoint motor2  ;
      public PrismaticJoint spring1;
      public PrismaticJoint spring2;
      public Fixture sensor;


      public coche() {

      }

      public void init(){


          int xi = -59;
          int yi = 85;

         PolygonShape sd = new PolygonShape();
         sd.setAsBox(1.8f, 0.30f);

         FixtureDef boxDef = new FixtureDef();

         BodyDef bodyDef = new BodyDef();
         bodyDef.position.set(xi+0f, yi+3.5f);
      
        bodyDef.type = BodyType.DYNAMIC;
        bodyDef.userData="coche";

         cart = world.createBody(bodyDef);

         //// El sensor de dentro del coche
PolygonShape sda = new PolygonShape();
            BodyDef bdlimit = new BodyDef();
            bdlimit.position = new Vec2(xi+0f, yi+3.5f);
            bdlimit.type = BodyType.DYNAMIC;
            sda.setAsBox(1.6f, 0.20f);
            bdlimit.userData = "interior";
            FixtureDef fds = new FixtureDef();
            fds.shape=sda;

            fds.isSensor = true;
        //    fd.filter.groupIndex=-1;

           // Body b = world.createBody(bdlimit);
            sensor = cart.createFixture(fds);
            sensor.setUserData("interior");



         /// fin del sensor


         
         boxDef.shape = sd;
         boxDef.density = 1000.0f;
         boxDef.friction = 0.5f;
         boxDef.restitution = 0.2f;
         boxDef.filter.groupIndex = -1;


          Fixture f_coche = cart.createFixture(boxDef);
          f_coche.setUserData("coche");


        // boxDef.density = 1;
  
        bodyDef.type = BodyType.DYNAMIC;
        bodyDef.userData="coche";
         // add the axles //
         bodyDef.angle =  (float) (2 * Math.PI -1);
         bodyDef.position.set(xi+1.5f, yi+3.0f);
         axle1 = world.createBody(bodyDef);

         sd = new PolygonShape();
         sd.setAsBox(0.8f, 0.1f);

         boxDef.shape = sd;

         Fixture a1 = axle1.createFixture(boxDef);
          a1.setUserData("coche");

         PrismaticJointDef prismaticJointDef = new PrismaticJointDef();
         prismaticJointDef.initialize(cart, axle1, axle1.getWorldCenter(),  new Vec2((float)Math.cos(Math.PI/3), (float) -Math.sin(Math.PI/3)));
         prismaticJointDef.lowerTranslation = -0.2f;
         prismaticJointDef.upperTranslation = 0.2f;
         prismaticJointDef.enableLimit = true;
        prismaticJointDef.enableMotor = true;
         prismaticJointDef.maxMotorForce = 20000.0f;
         prismaticJointDef.motorSpeed = 100.0f;
      
         PrismaticJoint spring1 = (PrismaticJoint)  world.createJoint(prismaticJointDef);


           bodyDef.angle =  (float) (-2 * Math.PI +1);
         bodyDef.position.set(xi-1.5f, yi+3.0f);
         axle2 = world.createBody(bodyDef);

         sd = new PolygonShape();
         sd.setAsBox(0.8f, 0.1f);

         boxDef.shape = sd;

         Fixture a2 = axle2.createFixture(boxDef);
         a2.setUserData("coche");

         prismaticJointDef = new PrismaticJointDef();
         prismaticJointDef.initialize(cart, axle2, axle2.getWorldCenter(),  new Vec2((float)-Math.cos(Math.PI/3), (float) -Math.sin(Math.PI/3)));
         prismaticJointDef.lowerTranslation = -0.2f;
         prismaticJointDef.upperTranslation = 0.2f;
         prismaticJointDef.enableLimit = true;
        prismaticJointDef.enableMotor = true;
         prismaticJointDef.maxMotorForce = 20000.0f;
         prismaticJointDef.motorSpeed = 100.0f;

         PrismaticJoint spring2 = (PrismaticJoint)  world.createJoint(prismaticJointDef);





         // add wheels //

         CircleShape circleDef = new CircleShape();
        circleDef.m_radius = 1f;
          FixtureDef fd = new FixtureDef();
          fd.shape = circleDef ;
          fd.density = 100.0f;
       
         fd.friction = 5f;
        fd.restitution = 0.2f;
         fd.filter.groupIndex = -1;

         for (int i = 0; i < 2; i++) {

            bodyDef = new BodyDef();
            bodyDef.userData="coche";
            bodyDef.type = BodyType.DYNAMIC;
            if (i == 0) bodyDef.position.set((float)(axle1.getWorldCenter().x + 0.8*Math.cos(Math.PI/3)), (float)(axle1.getWorldCenter().y - 0.8*Math.sin(Math.PI/3)));
            else bodyDef.position.set((float)(axle2.getWorldCenter().x - 0.8*Math.cos(-Math.PI/3)),(float) (axle2.getWorldCenter().y + 0.8*Math.sin(-Math.PI/3)));
            bodyDef.allowSleep = false;

            if (i == 0) wheel1 = world.createBody(bodyDef);
            else wheel2 = world.createBody(bodyDef);

            if (i == 0)
            {
               Fixture w1 =  wheel1.createFixture(fd);
               w1.setUserData("coche");

             }
            else
            {
               
                Fixture w2 =  wheel2.createFixture(fd);
               w2.setUserData("coche");

            }
         /*   (i == 0 ? wheel1 : wheel2).createShape(circleDef);
            (i == 0 ? wheel1 : wheel2).SetMassFromShapes();*/

         }


         // add joints //
        RevoluteJointDef revoluteJointDef = new RevoluteJointDef();
        revoluteJointDef.enableMotor = true;

         revoluteJointDef.initialize(axle1, wheel1, wheel1.getWorldCenter());
         motor1 = (RevoluteJoint) world.createJoint(revoluteJointDef);

         revoluteJointDef.initialize(axle2, wheel2, wheel2.getWorldCenter());
         motor2 = (RevoluteJoint) world.createJoint(revoluteJointDef);

         motor1.setMotorSpeed(-20f);
         motor1.setMaxMotorTorque(8500f);

         motor2.setMotorSpeed(-20f);
         motor2.setMaxMotorTorque(8500f);

      } 

   }

